/****************************************************************************/
/* File: scs-controller.h                                                   */
/* Desc: Specification file for the input game controller type              */
/* Created: 2014-11-16                                                      */
/* Revised: 2014-11-22                                                      */
/* Authors: Sterling P. de Mille                                            */
/****************************************************************************/

// include once
#ifndef _SCS_CONTROLLER_H_
#define _SCS_CONTROLLER_H_

// core data types
#include "../Core/scs-types.h"

// SDL framework
#include <SDL/SDL.h>

// assert support
#include <assert.h>

using namespace std;

// input game controller state
struct SCScontrolstate {
	SCSint16 iLeftTrigger;
	SCSint16 iRightTrigger;

	SCSint16 iLeftThumbstickX;
	SCSint16 iLeftThumbstickY;
	SCSint16 iRightThumbstickX;
	SCSint16 iRightThumbstickY;

	SCSint32u iButtonStates;
	SCSint32u iDpadState;
};

// input game controller input map
struct SCScontrolmap {
	SCSint aiButtons[32];
	SCSint aiAxes[6];
	SCSint aiDpad[16];
};

// input game controller type
class SCScontroller {
protected:

	SCScontrolstate m_kCurrentState;
	SCScontrolstate m_kPreviousState;
	SDL_Joystick* m_pkController;
	SCSbool m_iControllerActive;
	SCSbool m_iControllerConnected;
	SCSfloat m_fDeadZone;

	static SCScontroller* m_pkSingleton;

public:

	const static SCSint BUTTON_CONTROL_SINGLE = 1;
	const static SCSint BUTTON_CONTROL_LEFT = 8;
	const static SCSint BUTTON_CONTROL_RIGHT = 9;
	const static SCSint BUTTON_CONTROL_CENTER = 9;
	const static SCSint BUTTON_SHOULDER_SINGLE = 4;
	const static SCSint BUTTON_SHOULDER_LEFT = 4;
	const static SCSint BUTTON_SHOULDER_RIGHT = 5;
	const static SCSint BUTTON_SHOULDER_CENTER = 5;
	const static SCSint BUTTON_TRIGGER_SINGLE = 6;
	const static SCSint BUTTON_TRIGGER_LEFT = 6;
	const static SCSint BUTTON_TRIGGER_RIGHT = 7;
	const static SCSint BUTTON_TRIGGER_CENTER = 7;
	const static SCSint BUTTON_THUMBSTICK_SINGLE = 10;
	const static SCSint BUTTON_THUMBSTICK_LEFT = 10;
	const static SCSint BUTTON_THUMBSTICK_RIGHT = 11;
	const static SCSint BUTTON_THUMBSTICK_CENTER = 11;
	const static SCSint BUTTON_FACE_SINGLE = 0;
	const static SCSint BUTTON_FACE_LEFT = 0;
	const static SCSint BUTTON_FACE_BOTTOM = 1;
	const static SCSint BUTTON_FACE_CENTER = 1;
	const static SCSint BUTTON_FACE_RIGHT = 2;
	const static SCSint BUTTON_FACE_TOP = 3;

	const static SCSint DPAD_UP = 1;
	const static SCSint DPAD_DOWN = 2;
	const static SCSint DPAD_LEFT = 4;
	const static SCSint DPAD_RIGHT = 8;
	const static SCSint DPAD_UPLEFT = 5;
	const static SCSint DPAD_UPRIGHT = 9;
	const static SCSint DPAD_DOWNLEFT = 6;
	const static SCSint DPAD_DOWNRIGHT = 10;

	const static SCSint AXIS_THUMBSTICK_LEFT_X = 0;
	const static SCSint AXIS_THUMBSTICK_LEFT_Y = 1;
	const static SCSint AXIS_THUMBSTICK_RIGHT_X = 2;
	const static SCSint AXIS_THUMBSTICK_RIGHT_Y = 3;
	const static SCSint AXIS_TRIGGER_LEFT = 4;
	const static SCSint AXIS_TRIGGER_RIGHT = 5;

	SCScontroller ();
	~SCScontroller ();

	void ActivateController ();
	SCSbool ControllerActive ();
	SCSbool ControllerConnected ();

	SCScontrolmap GamepadMap () const;
	SCScontrolmap XboxMap () const;

	void SetDeadZone (SCSfloat fDeadZone);
	SCSfloat GetDeadZone ();

	SCSbool ButtonPress (SCSint iButton);
	SCSbool ButtonRelease (SCSint iButton);
	SCSbool ButtonPressed (SCSint iButton);
	SCSbool ButtonReleased (SCSint iButton);
	SCSint ButtonPosition (SCSint iButton);
	SCSint ButtonMotion (SCSint iButton);

	SCSfloat AxisPosition (SCSint iAxis);
	SCSfloat AxisMotion (SCSint iAxis);
	SCSint AxisPressed (SCSint iAxis);
	SCSbool AxisReleased (SCSint iAxis);
	SCSint AxisPress (SCSint iAxis);
	SCSbool AxisRelease (SCSint iAxis);

	SCSbool DpadPress (SCSint iDpadDirection);
	SCSbool DpadRelease (SCSint iDpadDirection);
	SCSbool DpadPressed (SCSint iDpadDirection);
	SCSbool DpadReleased (SCSint iDpadDirection);

	void Update ();
	void ClearState ();

	SCSint ButtonCount ();
	SCSint AxisCount ();
	SCSint DpadCount ();

	SCSbool ControllerGen1 ();
	SCSbool ControllerGen2 ();
	SCSbool ControllerGen3 ();
	SCSbool ControllerGen4 ();
	SCSbool ControllerGen5 ();
	SCSbool ControllerGen6 ();
	SCSbool ControllerGen7 ();

	SCSbool AtariCompatible ();
	SCSbool NintendoCompatible ();
	SCSbool SegaCompatible ();
	SCSbool SegaGenesisCompatible ();
	SCSbool SuperNintendoCompatible ();
	SCSbool SegaSaturnCompatible ();
	SCSbool Nintendo64Compatible ();
	SCSbool SegaDreamcastCompatible ();
	SCSbool GamepadCompatible ();
	SCSbool ArcadepadCompatible ();
	SCSbool XboxCompatible ();
	SCSbool PlaystationCompatible ();

	static SCScontroller* Singleton ();
};

#endif // _SCS_CONTROLLER_H_
